home *** CD-ROM | disk | FTP | other *** search
- /* ERROR.C
- ************************************************************************
- * *
- * PC Scheme/Geneva 4.00 Borland C code *
- * *
- * (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- * (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- * *
- *----------------------------------------------------------------------*
- * *
- * Basic Error Message Handling *
- * *
- *----------------------------------------------------------------------*
- * *
- * Created by: John Jensen Date: 1985 *
- * Revision history: *
- * - 5 Jun 86: Set or Ref of Fluid variable which is not defined in *
- * fluid environment is now non-restartable from error *
- * processor or inspector. (rb) *
- * - 16 Feb 86: errors return to Scheme toplevel rather than aborting *
- * to DOS (tc) *
- * - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- * *
- * ``In nomine omnipotentii dei'' *
- ************************************************************************/
-
- #include <ctype.h>
- #include <conio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include "scheme.h"
-
- /************************************************************************/
- /* Wrong Number of Arguments to a Closure */
- /************************************************************************/
- #define NUM_ARGS 16 /* offset of operand count in a closure object */
- void wrong_args(int args_passed, REGPTR closure)
- {
- int expected; /* the number of arguments expected */
- unsigned page, disp; /* page/displacement parts of closure pointer */
- char msg[100];
-
-
- /* determine the number of arguments expected */
- page = CORRPAGE(closure->page);
- disp = closure->disp;
- if( ptype[page] == CONTTYPE )
- expected = 1;
- expected = get_word(page, disp + NUM_ARGS);
-
- sprintf( msg, "Invalid argument count: Function expected %d%s argument(s)\n"
- "but was called with %%d as follows:",
- expected > 0 ? expected : ~expected,
- expected > 0 ? "" : " or more");
-
- arg_err( closure, args_passed, msg );
- }
-
- /************************************************************************/
- /* Local Support-- Cons up "call" expression, output message text */
- /************************************************************************/
- void arg_err( REGPTR ftn, int args_passed, char msg[] )
- {
- int i;
- REGPTR this_reg;
- char newmsg[100];
-
- sprintf( newmsg, msg, args_passed );
-
- /* cons up the function and arguments into a list */
- this_reg = regs + args_passed; /* pointer to last argument register */
- tmp_reg = nil_reg;
- for (i = 0; i < args_passed; i++, this_reg--)
- cons(&tmp_reg, this_reg, &tmp_reg);
- cons(&tmp_reg, ftn, &tmp_reg); /* put procedure object at front of list */
-
- set_error(1, newmsg, &tmp_reg); /* set up the error message text and irritant */
- }
-
- /************************************************************************/
- /* Error-- Attempted to call a non-procedural object */
- /************************************************************************/
- void not_procedural(REGPTR non_ftn_obj, int args_passed)
- {
- arg_err( non_ftn_obj, args_passed,
- "Attempt to call a non-procedural object with %d argument(s) as follows:");
- }
-
- /************************************************************************/
- /* Error-- Symbol Not Fluidly Bound */
- /************************************************************************/
- #pragma argsused
- void not_fluidly_bound(unsigned page, unsigned disp, REGPTR source)
- {
- /* create pointer to symbol and set up error parameters */
- tmp_reg.page = ADJPAGE(page);
- tmp_reg.disp = disp;
- set_numeric_error(1, SET_FLUID_ERROR, &tmp_reg);
- }
-
- /************************************************************************/
- /* Error-- Symbol Not Globally Bound */
- /************************************************************************/
- #pragma argsused
- void not_globally_bound(unsigned page, unsigned disp, REGPTR source)
- {
- /* create pointer to symbol and set up error parameters */
- tmp_reg.page = ADJPAGE(page);
- tmp_reg.disp = disp;
- set_numeric_error(0, SET_GLOBAL_ERROR, &tmp_reg);
- }
-
- /************************************************************************/
- /* Error-- Symbol Not Lexically Bound */
- /************************************************************************/
- void not_lexically_bound(unsigned page, unsigned disp)
- {
- /* create pointer to symbol and set up error parameters */
- tmp_reg.page = ADJPAGE(page);
- tmp_reg.disp = disp;
- set_numeric_error(0, SET_LEXICAL_ERROR, &tmp_reg);
- }
-
- /************************************************************************/
- /* Error-- Symbol Not Bound */
- /************************************************************************/
- #pragma argsused
- void sym_undefined(unsigned page, unsigned disp, REGPTR env, REGPTR dest)
- {
- int error_number; /* numeric error code */
- int error_restart; /* Can you resume from error?
- * 0=yes,1=no */
-
- error_restart = 0; /* Default to resumable */
- if (env == &gnv_reg)
- error_number = REF_GLOBAL_ERROR;
- else {
- if (env == &fnv_reg) {
- error_number = REF_FLUID_ERROR;
- error_restart = 1; /* Can't continue from fluid error */
- } else
- error_number = REF_LEXICAL_ERROR;
- }
-
- /* create pointer to undefined symbol and set message parameters */
- tmp_reg.page = ADJPAGE(page);
- tmp_reg.disp = disp;
- set_numeric_error(error_restart, error_number, &tmp_reg);
- }
-
- /************************************************************************/
- /* malloc error */
- /************************************************************************/
- void malloc_error(char *routine)
- {
- zprintf("[VM INTERNAL ERROR] %s: malloc error\n", routine);
- zprintf("Press any key to return to Scheme toplevel.\n");
- GETCH();
- force_reset();
- exit(0xff);
- }
-
- /************************************************************************/
- /* set error condition */
- /************************************************************************/
- void set_error(int code, char *message, REGPTR irritant)
- {
- /* bind error code to the symbol |*error-code*| */
- c_push(&tmp_reg);
- intern(&tm2_reg, "*ERROR-CODE*", 12);
- tmp_reg.page = ADJPAGE(SPECFIX);
- tmp_reg.disp = code;
- sym_bind(&tm2_reg, &tmp_reg, &gnv_reg);
-
- /* bind error message text to the symbol |*error-message*| */
- intern(&tm2_reg, "*ERROR-MESSAGE*", 15);
- alloc_string(&tmp_reg, message);
- sym_bind(&tm2_reg, &tmp_reg, &gnv_reg);
-
- /* bind irritant to the symbol |*irritant*| */
- c_pop(&tmp_reg);
- intern(&tm2_reg, "*IRRITANT*", 10);
- sym_bind(&tm2_reg, irritant, &gnv_reg);
- }
-
- /************************************************************************/
- /* set numeric error condition */
- /************************************************************************/
- void set_numeric_error(int code, int error_number, REGPTR irritant)
- {
- REG lcl_reg;
-
- lcl_reg.page = ADJPAGE( SPECFIX );
- lcl_reg.disp = code;
-
- /* bind error code to the symbol |*ERROR-CODE*| */
- intern(&tm2_reg, "*ERROR-CODE*", 12);
- sym_bind(&tm2_reg, &lcl_reg, &gnv_reg);
-
- /* bind error message text to the symbol |*ERROR-MESSAGE*| */
- intern(&tm2_reg, "*ERROR-MESSAGE*", 15);
- lcl_reg.disp = error_number;
- sym_bind(&tm2_reg, &lcl_reg, &gnv_reg);
-
- /* bind irritant to the symbol |*IRRITANT*| */
- intern(&tm2_reg, "*IRRITANT*", 10);
- sym_bind(&tm2_reg, irritant, &gnv_reg);
- }
-
- /************************************************************************/
- /* Process Invalid Source Operand Condition */
- /************************************************************************/
- void set_src_error(char *op, int args, ...)
- {
- int i;
- REGPTR *reg_ptr;
- va_list argptr;
-
- tmp_reg = nil_reg;
-
- va_start(argptr, args);
- reg_ptr = &va_arg(argptr, REGPTR);
-
- for (i = args-1; i >= 0; i--)
- cons(&tmp_reg, reg_ptr[i], &tmp_reg);
- intern(&tm2_reg, op, strlen(op));
- cons(&tmp_reg, &tm2_reg, &tmp_reg);
- set_numeric_error(1, INVALID_OPERAND_ERROR, &tmp_reg);
-
- va_end(argptr);
- }
-
- /************************************************************************/
- /* ERRMSG(code) */
- /* This simply prints whatever error message is called */
- /* for by CODE. */
- /************************************************************************/
- void errmsg(int code)
- {
- switch (code) {
- case QUOTERR:
- zprintf("Bad quote form\n");
- break;
- case DOTERR:
- zprintf("Bad dot form\n");
- break;
- case RPARERR:
- zprintf(") before (\n");
- break;
- case PORTERR:
- zprintf("Wrong port direction\n");
- break;
- case FULLERR:
- zprintf("Disk full\n");
- break;
- case HEAPERR:
- zprintf("Heap space exhausted\n");
- zprintf("Press any key to return to Scheme toplevel.\n"); /* rb */
- GETCH(); /* rb */
- force_reset();
- break;
- case OVERERR:
- zprintf("Flonum overflow\n");
- break;
- case DIV0ERR:
- zprintf("Divide by zero\n");
- break;
- case EOFERR:
- /* Don't print a message for end-of-file */
- break;
- case SHARPERR:
- zprintf("#-macro error\n");
- break;
- }
- }
-
- void checkstack()
- {
- if (stkspc() < 64)
- {
- zprintf("\n[VM ERROR encountered!] PC stack overflow\n"
- "Attempting to execute SCHEME-RESET [Returning to top level]\n");
- force_reset();
- }
- }
-